{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Logistic 回归--Pima Indians Diabetes Data Set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数据说明：<br>\n",
    "Pima Indians Diabetes Data Set（皮马印第安人糖尿病数据集） 根据现有的医疗信息预测5年内皮马印第安人糖尿病发作的概率。<br>   \n",
    "\n",
    "数据集共9个字段: <br>\n",
    "0列为怀孕次数；<br>\n",
    "1列为口服葡萄糖耐量试验中2小时后的血浆葡萄糖浓度；<br>\n",
    "2列为舒张压（单位:mm Hg）<br>\n",
    "3列为三头肌皮褶厚度（单位：mm）<br>\n",
    "4列为餐后血清胰岛素（单位:mm）<br>\n",
    "5列为体重指数（体重（公斤）/ 身高（米）^2）<br>\n",
    "6列为糖尿病家系作用<br>\n",
    "7列为年龄<br>\n",
    "8列为分类变量（0或1）<br>\n",
    "\n",
    "数据链接：https://archive.ics.uci.edu/ml/datasets/Pima+Indians+Diabetes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "#评价指标为logloss\n",
    "from sklearn.metrics import log_loss\n",
    "\n",
    "from matplotlib import pyplot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pregnants</th>\n",
       "      <th>Plasma_glucose_concentration</th>\n",
       "      <th>blood_pressure</th>\n",
       "      <th>Triceps_skin_fold_thickness</th>\n",
       "      <th>serum_insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>Diabetes_pedigree_function</th>\n",
       "      <th>Age</th>\n",
       "      <th>Target</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.639947</td>\n",
       "      <td>0.866045</td>\n",
       "      <td>-0.031990</td>\n",
       "      <td>0.670643</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>0.166619</td>\n",
       "      <td>0.468492</td>\n",
       "      <td>1.425995</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.844885</td>\n",
       "      <td>-1.205066</td>\n",
       "      <td>-0.528319</td>\n",
       "      <td>-0.012301</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>-0.852200</td>\n",
       "      <td>-0.365061</td>\n",
       "      <td>-0.190672</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.233880</td>\n",
       "      <td>2.016662</td>\n",
       "      <td>-0.693761</td>\n",
       "      <td>-0.012301</td>\n",
       "      <td>-0.181541</td>\n",
       "      <td>-1.332500</td>\n",
       "      <td>0.604397</td>\n",
       "      <td>-0.105584</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.844885</td>\n",
       "      <td>-1.073567</td>\n",
       "      <td>-0.528319</td>\n",
       "      <td>-0.695245</td>\n",
       "      <td>-0.540642</td>\n",
       "      <td>-0.633881</td>\n",
       "      <td>-0.920763</td>\n",
       "      <td>-1.041549</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-1.141852</td>\n",
       "      <td>0.504422</td>\n",
       "      <td>-2.679076</td>\n",
       "      <td>0.670643</td>\n",
       "      <td>0.316566</td>\n",
       "      <td>1.549303</td>\n",
       "      <td>5.484909</td>\n",
       "      <td>-0.020496</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   pregnants  Plasma_glucose_concentration  blood_pressure  \\\n",
       "0   0.639947                      0.866045       -0.031990   \n",
       "1  -0.844885                     -1.205066       -0.528319   \n",
       "2   1.233880                      2.016662       -0.693761   \n",
       "3  -0.844885                     -1.073567       -0.528319   \n",
       "4  -1.141852                      0.504422       -2.679076   \n",
       "\n",
       "   Triceps_skin_fold_thickness  serum_insulin       BMI  \\\n",
       "0                     0.670643      -0.181541  0.166619   \n",
       "1                    -0.012301      -0.181541 -0.852200   \n",
       "2                    -0.012301      -0.181541 -1.332500   \n",
       "3                    -0.695245      -0.540642 -0.633881   \n",
       "4                     0.670643       0.316566  1.549303   \n",
       "\n",
       "   Diabetes_pedigree_function       Age  Target  \n",
       "0                    0.468492  1.425995       1  \n",
       "1                   -0.365061 -0.190672       0  \n",
       "2                    0.604397 -0.105584       1  \n",
       "3                   -0.920763 -1.041549       0  \n",
       "4                    5.484909 -0.020496       1  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#读取数据\n",
    "train = pd.read_csv(\"FE_pima-indians-diabetes.csv\")\n",
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 768 entries, 0 to 767\n",
      "Data columns (total 9 columns):\n",
      "pregnants                       768 non-null float64\n",
      "Plasma_glucose_concentration    768 non-null float64\n",
      "blood_pressure                  768 non-null float64\n",
      "Triceps_skin_fold_thickness     768 non-null float64\n",
      "serum_insulin                   768 non-null float64\n",
      "BMI                             768 non-null float64\n",
      "Diabetes_pedigree_function      768 non-null float64\n",
      "Age                             768 non-null float64\n",
      "Target                          768 non-null int64\n",
      "dtypes: float64(8), int64(1)\n",
      "memory usage: 54.1 KB\n"
     ]
    }
   ],
   "source": [
    "train.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(768, 9)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train = train[\"Target\"]\n",
    "x_train = train.drop([\"Target\"], axis=1)\n",
    "\n",
    "#特征重要性的可视化\n",
    "feat_names = x_train.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模型训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# default Logistic Regression "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "lr = LogisticRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "logloss of each fold is  [0.48797856 0.53011593 0.4562292  0.422546   0.48392885]\n",
      "cv logloss is  0.47615970944434044\n"
     ]
    }
   ],
   "source": [
    "#交叉验证用于评估模型性能和进行超参数调优\n",
    "#分类任务中交叉验证缺省是采用StratifiedKFold\n",
    "from sklearn.model_selection import cross_val_score\n",
    "\n",
    "loss = cross_val_score(lr, x_train, y_train, cv = 5, scoring = \"neg_log_loss\")\n",
    "print (\"logloss of each fold is \", -loss)\n",
    "print (\"cv logloss is \", -loss.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正则化的Logistic Regression及超参数调优 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Logistic回归需要调整的超参数有:C(正则参数)和正则函数penalty (L2/L1)<br/>\n",
    "目标函数为:J = C * sum(logloss(f(xi), yi)) + penalty<br/>\n",
    "\n",
    "超参数调优步骤:<br/>\n",
    "设置候选参数集合<br/>\n",
    "生成一个GridSearchCV的实例<br/>\n",
    "调用GridSearchCV的fit函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "       estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='warn',\n",
       "          n_jobs=None, penalty='l2', random_state=None, solver='warn',\n",
       "          tol=0.0001, verbose=0, warm_start=False),\n",
       "       fit_params=None, iid='warn', n_jobs=4,\n",
       "       param_grid={'penalty': ['l1', 'l2'], 'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring='neg_log_loss', verbose=0)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "#需要调优的参数\n",
    "penaltys = [\"l1\",\"l2\"]\n",
    "Cs = [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "\n",
    "lr_penalty = LogisticRegression()\n",
    "grid = GridSearchCV(lr_penalty, tuned_parameters, cv = 5, scoring = \"neg_log_loss\", n_jobs = 4, verbose = 0)\n",
    "grid.fit(x_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.4760252267175665\n",
      "{'C': 1, 'penalty': 'l1'}\n"
     ]
    }
   ],
   "source": [
    "print(-grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coeffient</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Plasma_glucose_concentration</td>\n",
       "      <td>[1.1284405705686287]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>BMI</td>\n",
       "      <td>[0.6290661405198591]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>pregnants</td>\n",
       "      <td>[0.4096781099019902]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Diabetes_pedigree_function</td>\n",
       "      <td>[0.2793362941287718]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Age</td>\n",
       "      <td>[0.14381575866224022]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Triceps_skin_fold_thickness</td>\n",
       "      <td>[0.024771128512594807]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>serum_insulin</td>\n",
       "      <td>[-0.08404359559742888]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>blood_pressure</td>\n",
       "      <td>[-0.0929396692394756]</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                        columns               coeffient\n",
       "1  Plasma_glucose_concentration    [1.1284405705686287]\n",
       "5                           BMI    [0.6290661405198591]\n",
       "0                     pregnants    [0.4096781099019902]\n",
       "6    Diabetes_pedigree_function    [0.2793362941287718]\n",
       "7                           Age   [0.14381575866224022]\n",
       "3   Triceps_skin_fold_thickness  [0.024771128512594807]\n",
       "4                 serum_insulin  [-0.08404359559742888]\n",
       "2                blood_pressure   [-0.0929396692394756]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\"columns\":list(feat_names), \"coeffient\":list(grid.best_estimator_.coef_.T)})\n",
    "df.sort_values(by = [\"coeffient\"],ascending = False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#plot CV误差曲线\n",
    "test_means = -grid.cv_results_[\"mean_test_score\"]\n",
    "test_stds = grid.cv_results_[\"std_test_score\"]\n",
    "train_means = -grid.cv_results_[\"mean_train_score\"]\n",
    "train_stds = grid.cv_results_[\"std_train_score\"]\n",
    "\n",
    "#plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs,number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs,number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs,number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs,number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i,value in enumerate(penaltys):\n",
    "    pyplot.errorbar(x_axis, test_scores[:,i], yerr=test_stds[:,i], label = penaltys[i]+\"Test\")\n",
    "    pyplot.errorbar(x_axis, train_scores[:,i], yerr=train_stds[:,i], label = penaltys[i]+\"Train\")\n",
    "    \n",
    "pyplot.legend()\n",
    "pyplot.xlabel(\"log(C)\")\n",
    "pyplot.ylabel(\"logloss\")\n",
    "pyplot.savefig(\"LogisticGridSearchCV_C.png\")\n",
    "\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "L1正则和L2正则下,不同正则参数C对应模型在训练集及测试集上的正确率,<br>\n",
    "在训练集上C越大(正则越少)的模型性能越好;<br>\n",
    "但在测试集上当C=1时性能最好,L1正则<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 按照正确率做为评价指标 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.7747395833333334\n",
      "{'C': 0.1, 'penalty': 'l2'}\n"
     ]
    }
   ],
   "source": [
    "penaltys = [\"l1\",\"l2\"]\n",
    "Cs = [0.001,0.01,0.1,1,10,100,1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "\n",
    "lr_penalty = LogisticRegression()\n",
    "#缺省scoring为正确率\n",
    "grid = GridSearchCV(lr_penalty, tuned_parameters, cv = 5)\n",
    "grid.fit(x_train, y_train)\n",
    "\n",
    "print(grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>columns</th>\n",
       "      <th>coeffient</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Plasma_glucose_concentration</td>\n",
       "      <td>[0.9977309169127752]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>BMI</td>\n",
       "      <td>[0.5460044910698728]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>pregnants</td>\n",
       "      <td>[0.3616713513905089]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Diabetes_pedigree_function</td>\n",
       "      <td>[0.2599038326076921]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Age</td>\n",
       "      <td>[0.1554435734114967]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Triceps_skin_fold_thickness</td>\n",
       "      <td>[0.05966520979020307]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>serum_insulin</td>\n",
       "      <td>[-0.04513553103768543]</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>blood_pressure</td>\n",
       "      <td>[-0.06486609661370454]</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                        columns               coeffient\n",
       "1  Plasma_glucose_concentration    [0.9977309169127752]\n",
       "5                           BMI    [0.5460044910698728]\n",
       "0                     pregnants    [0.3616713513905089]\n",
       "6    Diabetes_pedigree_function    [0.2599038326076921]\n",
       "7                           Age    [0.1554435734114967]\n",
       "3   Triceps_skin_fold_thickness   [0.05966520979020307]\n",
       "4                 serum_insulin  [-0.04513553103768543]\n",
       "2                blood_pressure  [-0.06486609661370454]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.DataFrame({\"columns\":list(feat_names), \"coeffient\":list(grid.best_estimator_.coef_.T)})\n",
    "df.sort_values(by = [\"coeffient\"],ascending = False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#plot CV误差曲线\n",
    "test_means = -grid.cv_results_[\"mean_test_score\"]\n",
    "test_stds = grid.cv_results_[\"std_test_score\"]\n",
    "train_means = -grid.cv_results_[\"mean_train_score\"]\n",
    "train_stds = grid.cv_results_[\"std_train_score\"]\n",
    "\n",
    "#plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs,number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs,number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs,number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs,number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i,value in enumerate(penaltys):\n",
    "    pyplot.errorbar(x_axis, test_scores[:,i], yerr=test_stds[:,i], label = penaltys[i]+\"Test\")\n",
    "    pyplot.errorbar(x_axis, train_scores[:,i], yerr=train_stds[:,i], label = penaltys[i]+\"Train\")\n",
    "    \n",
    "pyplot.legend()\n",
    "pyplot.xlabel(\"log(C)\")\n",
    "pyplot.ylabel(\"accuary\")\n",
    "pyplot.savefig(\"LogisticGridSearchCV_C.png\")\n",
    "\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "l2\n",
      "0.1\n"
     ]
    }
   ],
   "source": [
    "print(grid.best_params_[\"penalty\"])\n",
    "print(grid.best_params_[\"C\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.36167135,  0.99773092, -0.0648661 ,  0.05966521, -0.04513553,\n",
       "         0.54600449,  0.25990383,  0.15544357]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid.best_estimator_.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
